using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
namespace Circus.CodeEditor
{
	public class RangeList2 : SortList<Range>
	{
		private class RangeComparer : IComparer<Range>
		{
			public int Compare(Range x, Range y)
			{
				int num = x.StartPoint.Y - y.StartPoint.Y;
				if (num == 0)
				{
					num = x.StartPoint.X - y.StartPoint.X;
				}
				return num;
			}
		}
		private class PointComparer : IComparer<Range>
		{
			public int Compare(Range x, Range y)
			{
				Point startPoint = x.StartPoint;
				Point startPoint2 = y.StartPoint;
				int num = startPoint.Y - startPoint2.Y;
				if (num == 0)
				{
					num = startPoint.X - startPoint2.X;
				}
				return num;
			}
		}
		private class PointHitTest : IComparer<Range>
		{
			public int Compare(Range x, Range y)
			{
				Point startPoint = x.StartPoint;
				Point endPoint = x.EndPoint;
				Point startPoint2 = y.StartPoint;
				int result;
				if (startPoint2.Y > startPoint.Y || (startPoint2.Y == startPoint.Y && startPoint2.X >= startPoint.X))
				{
					result = ((startPoint2.Y < endPoint.Y || (startPoint2.Y == endPoint.Y && startPoint2.X < endPoint.X)) ? 0 : -1);
				}
				else
				{
					result = 1;
				}
				return result;
			}
		}
		private class InclusiveLineHitTest : IComparer<Range>
		{
			public int Compare(Range x, Range y)
			{
				Point startPoint = x.StartPoint;
				Point endPoint = x.EndPoint;
				int y2 = y.StartPoint.Y;
				int result;
				if (y2 > startPoint.Y)
				{
					result = ((y2 <= endPoint.Y) ? 0 : -1);
				}
				else
				{
					result = 1;
				}
				return result;
			}
		}
		private class LineHitTest : IComparer<Range>
		{
			public int Compare(Range x, Range y)
			{
				Point startPoint = x.StartPoint;
				Point endPoint = x.EndPoint;
				int y2 = y.StartPoint.Y;
				int result;
				if (y2 >= startPoint.Y)
				{
					result = ((y2 <= endPoint.Y) ? 0 : -1);
				}
				else
				{
					result = 1;
				}
				return result;
			}
		}
		private SortRange topRange;
		private IComparer<Range> rangeComparer;
		private IComparer<Range> pointComparer;
		private IComparer<Range> pointHitTest;
		private IComparer<Range> inclusiveLineHitTest;
		private IComparer<Range> lineHitTest;
		private int updateCount;
		private bool needSort;
		public SortRange TopRange
		{
			get
			{
				return this.topRange;
			}
		}
		public int UpdateCount
		{
			get
			{
				return this.updateCount;
			}
		}
		protected void SortLevels()
		{
			this.topRange.Clear();
			IList<SortRange> list = new List<SortRange>();
			SortRange sortRange = this.topRange;
			for (int i = 0; i < base.Count; i++)
			{
				Range range = base[i];
				SortRange sortRange2 = new SortRange(range, i);
				while (list.Count > 0 && !sortRange.Contains(range))
				{
					sortRange = list[list.Count - 1];
					list.RemoveAt(list.Count - 1);
				}
				list.Add(sortRange);
				sortRange.Add(sortRange2);
				sortRange = sortRange2;
			}
		}
		protected int FindRangeIndex(Point point, IComparer<Range> comparer)
		{
			SortRange sortRange = this.topRange;
			int result = -1;
			Range obj = new Range(point, point);
			int index;
			while (sortRange.Ranges.FindLast(obj, out index, comparer))
			{
				sortRange = (SortRange)sortRange.Ranges[index];
				result = sortRange.Index;
			}
			return result;
		}
		protected int FindRangeIndex(int index, IComparer<Range> comparer)
		{
			SortRange sortRange = this.topRange;
			int result = -1;
			Range obj = new Range(0, index, 0, index);
			int index2;
			while (sortRange.Ranges.FindLast(obj, out index2, comparer))
			{
				sortRange = (SortRange)sortRange.Ranges[index2];
				result = sortRange.Index;
			}
			return result;
		}
		protected Range FindRange(Point point, IComparer<Range> comparer)
		{
			SortRange sortRange = this.topRange;
			Range result = null;
			Range obj = new Range(point, point);
			int index;
			while (sortRange.Ranges.FindLast(obj, out index, comparer))
			{
				sortRange = (SortRange)sortRange.Ranges[index];
				result = sortRange.Range;
			}
			return result;
		}
		protected Range FindRange(int index, IComparer<Range> comparer)
		{
			SortRange sortRange = this.topRange;
			Range result = null;
			Range obj = new Range(0, index, 0, index);
			int index2;
			while (sortRange.Ranges.FindLast(obj, out index2, comparer))
			{
				sortRange = (SortRange)sortRange.Ranges[index2];
				result = sortRange.Range;
			}
			return result;
		}
		public RangeList2()
		{
			this.topRange = new TopRange();
			this.rangeComparer = new RangeList2.RangeComparer();
			this.pointComparer = new RangeList2.PointComparer();
			this.pointHitTest = new RangeList2.PointHitTest();
			this.lineHitTest = new RangeList2.LineHitTest();
			this.inclusiveLineHitTest = new RangeList2.InclusiveLineHitTest();
		}
		public virtual bool UpdatePosition(Range range, int x, int y, int deltaX, int deltaY)
		{
			Point point = range.StartPoint;
			bool result = false;
			if (SortList<Range>.UpdatePos(x, y, deltaX, deltaY, ref point, false))
			{
				range.StartPoint = point;
				result = true;
			}
			point = range.EndPoint;
			if (SortList<Range>.UpdatePos(x, y, deltaX, deltaY, ref point, true))
			{
				range.EndPoint = point;
				result = true;
			}
			return result;
		}
		public virtual bool BlockDeleting(Rectangle rect)
		{
			bool flag = false;
			this.BeginUpdate();
			try
			{
				flag = this.topRange.BlockDeleting(rect, this, this.pointComparer);
				if (flag)
				{
					this.SortLevels();
				}
			}
			finally
			{
				this.EndUpdate(flag);
			}
			return flag;
		}
		public virtual bool PositionChanged(int x, int y, int deltaX, int deltaY)
		{
			return this.topRange.PositionChanged(x, y, deltaX, deltaY, this, this.pointComparer);
		}
		public new void Clear()
		{
			base.Clear();
			this.topRange.Clear();
		}
		public void CopyFrom(IList<Range> ranges)
		{
			this.BeginUpdate();
			try
			{
				this.Clear();
				foreach (Range current in ranges)
				{
					this.Add(current);
				}
			}
			finally
			{
				this.EndUpdate();
			}
		}
		public new void RemoveAt(int index)
		{
			base.RemoveAt(index);
			if (this.updateCount == 0)
			{
				this.SortLevels();
			}
		}
		public new int Add(Range item)
		{
			int result;
			if (this.updateCount == 0)
			{
				int num;
				if (base.FindLast(item, out num, this.rangeComparer))
				{
					this.RemoveAt(num);
				}
				this.Insert(num, item);
				result = num;
			}
			else
			{
				this.needSort = true;
				base.Add(item);
				result = base.Count - 1;
			}
			return result;
		}
		public Range FindRange(Point point)
		{
			return this.FindRange(point, this.pointHitTest);
		}
		public Range FindInclusiveRange(int index)
		{
			return this.FindRange(index, this.inclusiveLineHitTest);
		}
		public Range FindRange(int index)
		{
			return this.FindRange(index, this.lineHitTest);
		}
		public Range FindExactRange(Point point)
		{
			Range range = this.FindRange(point, this.pointHitTest);
			return (range != null && range.StartPoint.Equals(point)) ? range : null;
		}
		public Range FindExactRange(int index)
		{
			Range range = this.FindRange(index, this.lineHitTest);
			return (range != null && range.StartPoint.Y == index) ? range : null;
		}
		public void RemoveRange(Point point)
		{
			IList<int> list = new List<int>();
			SortRange sortRange = this.topRange;
			Range obj = new Range(point, point);
			int index;
			while (sortRange.Ranges.FindLast(obj, out index, this.pointHitTest))
			{
				if (sortRange.Index >= 0)
				{
					list.Add(sortRange.Index);
				}
				sortRange = (SortRange)sortRange.Ranges[index];
			}
			if (list.Count > 0)
			{
				this.BeginUpdate();
				try
				{
					for (int i = list.Count - 1; i >= 0; i--)
					{
						this.RemoveAt(list[i]);
					}
				}
				finally
				{
					this.EndUpdate();
				}
			}
		}
		public void RemoveRange(int index)
		{
			IList<int> list = new List<int>();
			SortRange sortRange = this.topRange;
			Range obj = new Range(0, index, 0, index);
			int index2;
			while (sortRange.Ranges.FindLast(obj, out index2, this.lineHitTest))
			{
				if (sortRange.Index >= 0)
				{
					list.Add(sortRange.Index);
				}
				sortRange = (SortRange)sortRange.Ranges[index2];
			}
			if (list.Count > 0)
			{
				this.BeginUpdate();
				try
				{
					for (int i = list.Count - 1; i >= 0; i--)
					{
						this.RemoveAt(list[i]);
					}
				}
				finally
				{
					this.EndUpdate();
				}
			}
		}
		public int GetRanges(List<Range> ranges)
		{
			ranges.Clear();
			foreach (Range current in this)
			{
				ranges.Add(current);
			}
			return ranges.Count;
		}
		public List<Range> GetRanges()
		{
			List<Range> list = new List<Range>();
			this.GetRanges(list);
			return list;
		}
		public int GetRanges(IList<Range> ranges, Point startpoint, Point endpoint)
		{
			ranges.Clear();
			SortRange x = new SortRange(new Range(startpoint, endpoint), 0);
			Range range = new Range();
			Range range2 = new Range();
			foreach (Range current in this)
			{
				range.StartPoint = current.StartPoint;
				range2.StartPoint = current.EndPoint;
				if (this.pointHitTest.Compare(x, range) == 0 && this.pointHitTest.Compare(x, range2) == 0)
				{
					ranges.Add(current);
				}
			}
			return ranges.Count;
		}
		public int GetRanges(IList<Range> ranges, Point point)
		{
			ranges.Clear();
			SortRange sortRange = this.topRange;
			Range obj = new Range(point, point);
			int index;
			while (sortRange.Ranges.FindLast(obj, out index, this.pointHitTest))
			{
				sortRange = (SortRange)sortRange.Ranges[index];
				if (sortRange.Range != null)
				{
					ranges.Add(sortRange.Range);
				}
			}
			return ranges.Count;
		}
		public int GetExactRanges(IList<Range> ranges, int index)
		{
			ranges.Clear();
			SortRange sortRange = this.topRange;
			Range obj = new Range(0, index, 0, index);
			int index2;
			while (sortRange.Ranges.FindLast(obj, out index2, this.lineHitTest))
			{
				sortRange = (SortRange)sortRange.Ranges[index2];
				if (sortRange.StartPoint.Y == index && sortRange.Range != null)
				{
					ranges.Add(sortRange.Range);
				}
			}
			return ranges.Count;
		}
		public int GetRanges(IList<Range> ranges, int index)
		{
			ranges.Clear();
			SortRange sortRange = this.topRange;
			Range obj = new Range(0, index, 0, index);
			int index2;
			while (sortRange.Ranges.FindLast(obj, out index2, this.lineHitTest))
			{
				sortRange = (SortRange)sortRange.Ranges[index2];
				if (sortRange.Range != null)
				{
					ranges.Add(sortRange.Range);
				}
			}
			return ranges.Count;
		}
		public new void Insert(int index, Range item)
		{
			base.Insert(index, item);
			if (this.updateCount == 0)
			{
				this.SortLevels();
			}
		}
		public int BeginUpdate()
		{
			this.updateCount++;
			return this.updateCount;
		}
		public int EndUpdate(bool update)
		{
			this.updateCount--;
			if (this.updateCount == 0 && update)
			{
				this.Update();
			}
			return this.updateCount;
		}
		public int EndUpdate()
		{
			return this.EndUpdate(true);
		}
		public virtual void Update()
		{
			if (this.needSort)
			{
				this.Sort();
			}
		}
		public new void Sort()
		{
			if (this.updateCount == 0)
			{
				this.needSort = false;
				base.Sort(this.rangeComparer);
				this.SortLevels();
			}
		}
	}
}
